home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
UNIXTOOL
/
MEMACS
/
C
/
Archimedes
next >
Wrap
Text File
|
1990-07-11
|
11KB
|
596 lines
/*
* The routines in this file provide support for the Archimedes and other
* compatible computers. It compiles into nothing if not an ARCHIMEDES driver
*/
#define termdef 1 /* don't define "term" external */
#include <stdio.h>
#include "estruct.h"
#include "eproto.h"
#include "edef.h"
#include "elang.h"
#if ACORN
#include "kernel.h"
#include "swis.h"
#define NROW 64 /* max number of rows allowable */
#define NCOL 144 /* max number of columns allowable */
#define MARGIN 8 /* min margin for extended lines */
#define SCRSIZ 64 /* size of scroll region for extended lines */
#define NPAUSE 200 /* number of times through update to pause */
#define BEL 0x07 /* BEL character */
#define ESC 0x1B /* ESC character */
#define SPACE 32 /* space character */
/* Vector and event handling */
#define EventOn 14
#define EventOff 13
#define KeyPress 0x0B
#define EventV 0x10
#define InsV 0x14
extern void Event_Handler(void);
extern void Insert_Handler(void);
/* OS interface functions */
static _kernel_swi_regs regs;
#define fx(a,x,y) (_kernel_osbyte(a,x,y))
#define swi(n) (_kernel_swi(n,®s,®s))
#define vdu(n) (void)(_kernel_oswrch(n))
#define vdu23(a,b,c,d,e,f,g,h,i) \
(void)( \
_kernel_oswrch(23), \
_kernel_oswrch(a), \
_kernel_oswrch(b), \
_kernel_oswrch(c), \
_kernel_oswrch(d), \
_kernel_oswrch(e), \
_kernel_oswrch(f), \
_kernel_oswrch(g), \
_kernel_oswrch(h), \
_kernel_oswrch(i) \
)
#define vdu19(c,m,r,g,b) \
(void)( \
_kernel_oswrch(19), \
_kernel_oswrch(c), \
_kernel_oswrch(m), \
_kernel_oswrch(r), \
_kernel_oswrch(g), \
_kernel_oswrch(b) \
)
int revflag = FALSE;
void armmove(int,int);
void armeeol(void);
void armputc(int);
void armeeop(void);
void armrev(int);
int armcres(char *);
void armbeep(void);
void armopen(void);
void armclose(void);
void armkopen(void);
void armkclose(void);
int fnclabel(int, int);
void esc_off(void);
void esc_on(void);
#define MDSENSE -1
int scinit(int);
/* The current display mode, and associated VDU variables */
int dmode = -1;
static int mode_var_defs[] =
{
0, /* Mode flags */
1, /* Maximum screen column */
2, /* Maximum screen row */
3, /* Maximum logical colour number */
-1
};
#define NVARS ((sizeof(mode_var_defs) / sizeof(int)) - 1)
static struct {
int modeflags;
int maxcol;
int maxrow;
int maxcolour;
}
mode_var_vals;
/* Functions to save and restore the VDU state */
void save_vdustate(void);
void restore_vdustate(void);
/* Saved values of the keyboard state */
static int esc_status;
static int cursor_status;
static int tab_status;
#if 0
static int kpad_status;
static int kpad_shift;
#endif
/* Vector handler private variables */
static struct {
int recursive;
int key;
int shift;
int ctrl;
int alt;
int international;
}
handler_vars;
static int fn_status[8];
#if COLOR
void armfcol(int);
void armbcol(int);
int ctran4[] =
{
0, /* Black */
1, /* Red */
2, /* Green == Yellow */
2, /* Yellow */
1, /* Blue == Red */
1, /* Magenta == Red */
2, /* Cyan == Yellow */
3 /* White */
};
int ctran255[] =
{
0x00, /* Black */
0x03, /* Red */
0x0C, /* Green */
0x0F, /* Yellow */
0x30, /* Blue */
0x33, /* Magenta */
0x3C, /* Cyan */
0x3F /* White, Gray */
};
#endif
typedef int (PASCAL NEAR *termfn)();
/*
* Standard terminal interface dispatch table. Most of the fields point into
* "termio" code.
*/
TERM term =
{
NROW-1, /* max number of rows allowable */
NROW-1, /* current number of rows used - set on init */
NCOL, /* max number of columns */
NCOL, /* current number of columns - set on init */
MARGIN, /* min margin for extended lines */
SCRSIZ, /* size of scroll region for extended lines */
NPAUSE, /* number of times through update to pause */
(termfn)armopen,
(termfn)armclose,
(termfn)armkopen,
(termfn)armkclose,
(termfn)ttgetc,
(termfn)armputc,
(termfn)ttflush,
(termfn)armmove,
(termfn)armeeol,
(termfn)armeeop,
(termfn)armbeep,
(termfn)armrev,
(termfn)armcres
#if COLOR
,
(termfn)armfcol,
(termfn)armbcol
#endif
};
#if COLOR
void armfcol (int color) /* set the current output color */
{
/* Not in teletext modes */
if ((mode_var_vals.modeflags & 0x02) != 0)
return;
switch (mode_var_vals.maxcolour)
{
case 1:
break;
case 3:
vdu(17);
vdu(ctran4[color & 0x07]);
break;
case 15:
vdu(17);
vdu(color);
break;
case 255:
vdu(17);
/* Special case for Grey == "Light Black" */
if (color == 8)
vdu(0x15);
else
vdu(ctran255[color & 0x07]);
/* Set the tint based on the high bit */
if (color & 0x08)
vdu23(17,0,0xC0,0,0,0,0,0,0);
else
vdu23(17,0,0x00,0,0,0,0,0,0);
break;
}
}
void armbcol (int color) /* set the current background color */
{
/* Not in teletext modes */
if ((mode_var_vals.modeflags & 0x02) != 0)
return;
switch (mode_var_vals.maxcolour)
{
case 1:
break;
case 3:
vdu(17);
vdu(128+ctran4[color & 0x07]);
break;
case 15:
vdu(17);
vdu(128+color);
break;
case 255:
vdu(17);
/* Special case for Grey == "Light Black" */
if (color == 8)
vdu(128+0x15);
else
vdu(128+ctran255[color & 0x07]);
/* Set the tint based on the high bit */
if (color & 0x08)
vdu23(17,1,0xC0,0,0,0,0,0,0);
else
vdu23(17,1,0x00,0,0,0,0,0,0);
break;
}
}
#endif
int spal (char *pstr)
{
return(FALSE);
}
void armmove (int row, int col)
{
vdu(31);
vdu(col);
vdu(row);
}
void armeeol (void) /* erase to the end of the line */
{
vdu23(8,5,6,0,0,0,0,0,0);
}
void armputc (int ch) /* put a character at the current position in the
current colors */
{
vdu(ch);
}
void armeeop (void)
{
#if COLOR
armfcol(gfcolor);
armbcol(gbcolor);
#endif
vdu23(8,4,10,0,0,0,0,0,0);
}
void armrev (int state) /* change reverse video state: TRUE = reverse, FALSE = normal */
{
/* Only in non-teletext modes */
if ((mode_var_vals.modeflags & 0x02) == 0)
{
if (revflag != state)
{
revflag = state;
vdu23(17,5,0,0,0,0,0,0,0);
}
}
}
int armcres (char *res) /* change screen resolution */
{
int mode = asc_int(res);
return(scinit(mode));
}
void armbeep (void)
{
vdu(BEL);
}
void armopen (void)
{
save_vdustate();
scinit(MDSENSE);
revflag = FALSE;
/* Initialise the handler variables */
handler_vars.recursive = 0;
handler_vars.key = 0;
handler_vars.shift = 0;
handler_vars.ctrl = 0;
handler_vars.alt = 0;
/* Check for the International Keyboard module */
regs.r[0] = 18;
regs.r[1] = (int)"InternationalKeyboard";
handler_vars.international = (swi(OS_Module) ? 0 : 1);
/* Now, open the keyboard */
ttopen();
/* Switch the escape key off here, rather than in armkopen(),
* as we cannot afford to switch escape back on except under
* very controlled conditions.
*/
esc_off();
}
void armclose (void)
{
restore_vdustate();
/* Switch the escape key back on here */
esc_on();
}
void esc_off (void)
{
esc_status = fx(229,1,0) & 0xFF;
}
void esc_on (void)
{
fx(229,esc_status,0);
}
static int init_mode;
static int init_var_defs[] =
{
155, /* Text foreground colour */
156, /* Text background colour */
-1
};
#define INIT_NVARS ((sizeof(init_var_defs) / sizeof(int)) - 1)
static struct {
int foreground;
int background;
}
init_var_vals;
void save_vdustate (void)
{
init_mode = (fx(135,0,0) >> 8) & 0xFF;
regs.r[0] = (int)init_var_defs;
regs.r[1] = (int)&init_var_vals;
swi(OS_ReadVduVariables);
}
void restore_vdustate (void)
{
if (init_mode != dmode)
{
vdu(22);
vdu(init_mode);
}
vdu(17);
vdu(init_var_vals.foreground);
vdu(17);
vdu(128+init_var_vals.background);
}
void armkopen (void) /* open the keyboard */
{
register int i;
/* Cursor keys */
cursor_status = fx(4,2,0) & 0xFF;
/* Tab key */
tab_status = fx(219,0x8A,0) & 0xFF;
/* Function keys */
for (i = 0; i < 8; ++i)
fn_status[i] = fx(221+i,2,0) & 0xFF;
#if 0
/* Numeric keypad */
kpad_status = fx(238,0xC0,0) & 0xFF;
kpad_shift = fx(254,0,0) & 0xFF;
#endif
/* Start recording changes of shift key status */
fx(EventOn,KeyPress,0);
regs.r[0] = EventV;
regs.r[1] = (int)Event_Handler;
regs.r[2] = (int)&handler_vars;
swi(OS_Claim);
/* Switch our keyboard translation on */
regs.r[0] = InsV;
regs.r[1] = (int)Insert_Handler;
regs.r[2] = (int)&handler_vars;
swi(OS_Claim);
}
void armkclose (void) /* close the keyboard */
{
register int i;
/* Cursor keys */
fx(4,cursor_status,0);
/* Tab key */
fx(219,tab_status,0);
/* Function keys */
for (i = 0; i < 8; ++i)
fx(221+i,fn_status[i],0);
#if 0
/* Numeric keypad */
fx(238,kpad_status,0);
fx(254,kpad_shift,0);
#endif
/* Finish recording changes of shift key status */
fx(EventOff,KeyPress,0);
regs.r[0] = EventV;
regs.r[1] = (int)Event_Handler;
regs.r[2] = (int)&handler_vars;
swi(OS_Release);
/* Switch our keyboard translation off */
regs.r[0] = InsV;
regs.r[1] = (int)Insert_Handler;
regs.r[2] = (int)&handler_vars;
swi(OS_Release);
}
/* Set the screen up in a given mode. If mode is MDSENSE, then retain the
* current mode. Saves the various mode parameters, and resizes the current
* window as required.
*/
int scinit (int mode)
{
if (mode == MDSENSE)
mode = (fx(135,0,0) >> 8) & 0xFF;
if (mode == dmode)
return(TRUE);
/* Check that the requested mode is valid */
regs.r[0] = mode;
swi(OS_CheckModeValid);
if (regs.r[0] != mode && regs.r[1] == -2)
return(FALSE);
if (regs.r[0] != mode)
mode = regs.r[0];
vdu(22);
vdu(mode);
regs.r[0] = (int)mode_var_defs;
regs.r[1] = (int)&mode_var_vals;
swi(OS_ReadVduVariables);
/* Correct the funny value for maxcol in 256-colour modes */
if (mode_var_vals.maxcolour == 63)
mode_var_vals.maxcolour = 255;
/* Set the palette in 16-colour modes */
if (mode_var_vals.maxcolour == 15)
{
vdu19(0,16,0x00,0x00,0x00); /* Black */
vdu19(1,16,0xCC,0x00,0x00); /* Red */
vdu19(2,16,0x00,0xCC,0x00); /* Green */
vdu19(3,16,0xCC,0xCC,0x00); /* Yellow */
vdu19(4,16,0x00,0x00,0xCC); /* Blue */
vdu19(5,16,0xCC,0x00,0xCC); /* Magenta */
vdu19(6,16,0x00,0xCC,0xCC); /* Cyan */
vdu19(7,16,0xCC,0xCC,0xCC); /* Grey */
vdu19(8,16,0x77,0x77,0x77); /* Gray == "Light Black" */
vdu19(9,16,0xFF,0x33,0x33); /* Light Red */
vdu19(10,16,0x33,0xFF,0x33); /* Light Green */
vdu19(11,16,0xFF,0xFF,0x33); /* Light Yellow */
vdu19(12,16,0x33,0x33,0xFF); /* Light Blue */
vdu19(13,16,0xFF,0x33,0xFF); /* Light Magenta */
vdu19(14,16,0x33,0xFF,0xFF); /* Light Cyan */
vdu19(15,16,0xFF,0xFF,0xFF); /* White */
}
newsize(TRUE,mode_var_vals.maxrow + 1);
newwidth(TRUE,mode_var_vals.maxcol + 1);
/* reset the $sres environment variable */
sprintf(sres, "%d", mode);
dmode = mode;
return(TRUE);
}
/* write a line out */
int scwrite (int row, char *outstr, int forg, int bacg)
{
/* row = row of screen to place outstr on */
/* outstr = string to write out (must be term.t_ncol long) */
/* forg = forground color of string to write */
/* bacg = background color */
vdu(31);
vdu(0);
vdu(row);
armfcol(forg);
armbcol(bacg);
regs.r[0] = (int)outstr;
swi(OS_Write0);
return 0;
}
#if FLABEL
int fnclabel(int f, int n) /* label a function key */
{
/* on machines with no function keys...don't bother */
return(TRUE);
}
#endif
#else
armhello()
{
}
#endif